package com.chain.BrotherExchange.viewmodel;

import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.MutableLiveData;
import android.support.annotation.NonNull;

import com.chain.BrotherExchange.data.DataRepository;
import com.chain.BrotherExchange.data.DataSource;
import com.chain.BrotherExchange.data.Resource;
import com.chain.BrotherExchange.data.model.EntrustQueue;
import com.chain.BrotherExchange.data.model.MarketPair;
import com.chain.BrotherExchange.data.model.OrderRecord;
import com.chain.BrotherExchange.data.model.Quotation;
import com.chain.BrotherExchange.data.model.QuotationTypes;
import com.chain.BrotherExchange.data.model.VisualQuotation;
import com.chain.BrotherExchange.utils.DateUtils;
import com.chain.BrotherExchange.widget.kline.KData;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 行情
 */
public class QuotationViewModel extends AndroidViewModel {

    // 交易对
    private String symbol;

    // K 线周期
    private String resolution = "15min";

    // 开始结束时间
    private long fromDate, toDate;

    private Timer mMarketPairTimer = new Timer();

    private DataSource.DataCallback<Resource<List<KData>>> mCallback;

    private MutableLiveData<Resource<List<Quotation.DataBean.ListBean>>> mQuotationLiveData;

    private MutableLiveData<Resource<List<QuotationTypes.DataBean.ListBean>>> mQuotationTypeLiveData;

    public QuotationViewModel(@NonNull Application application) {
        super(application);
        fromDate = DateUtils.weekLaterTimestamp(System.currentTimeMillis());
        mQuotationLiveData = new MutableLiveData<>();
        mQuotationTypeLiveData = new MutableLiveData<>();
    }

    public MutableLiveData<Resource<List<QuotationTypes.DataBean.ListBean>>> quotationTypes() {
        mQuotationTypeLiveData.setValue(Resource.loading());
        DataRepository.get().quotationType(result -> {
            QuotationTypes.DataBean resultData = result.getData();
            if (result.isSucceed() && resultData != null) {
                List<QuotationTypes.DataBean.ListBean> list = resultData.getList();
                if (list != null && !list.isEmpty()) {
                    mQuotationTypeLiveData.setValue(Resource.success(list));
                }
            } else if (result.isNotNetwork()) {
                mQuotationTypeLiveData.setValue(Resource.notNetwork());
            } else {
                mQuotationTypeLiveData.setValue(Resource.error(result.getMsg()));
            }
        });

        return mQuotationTypeLiveData;
    }

    public MutableLiveData<Resource<List<Quotation.DataBean.ListBean>>> quotationInfo(int type) {
        mQuotationLiveData.setValue(Resource.loading());

        DataRepository.get().quotationInfo(type, result -> {
            Quotation.DataBean resultData = result.getData();
            if (result.isSucceed() && resultData != null) {
                List<Quotation.DataBean.ListBean> list = resultData.getList();
                if (list != null && !list.isEmpty()) {
                    mQuotationLiveData.setValue(Resource.success(list));
                } else {
                    mQuotationLiveData.setValue(Resource.empty());
                }

            } else if (result.isNotNetwork()) {
                mQuotationLiveData.setValue(Resource.notNetwork());
            } else {
                mQuotationLiveData.setValue(Resource.error(result.getMsg()));
            }
        });

        return mQuotationLiveData;
    }

    // 15分K线
    public void minutesKLine() {
        resolution = "15min";
        fromDate = DateUtils.weekLaterTimestamp(System.currentTimeMillis());
        kLine(symbol, mCallback);
    }

    // 1小时K线
    public void anHourKLine() {
        resolution = "1hour";
        fromDate = DateUtils.afterMonthTimestamp(System.currentTimeMillis());
        kLine(symbol, mCallback);
    }

    // 4小时K线
    public void fourHoursKLine() {
        resolution = "4hour";
        fromDate = DateUtils.afterTwoMonthTimestamp(System.currentTimeMillis());
        kLine(symbol, mCallback);
    }

    // 1天K线
    public void oneDayKLine() {
        resolution = "1day";
        fromDate = DateUtils.afterSixMonthsTimestamp(System.currentTimeMillis());
        kLine(symbol, mCallback);
    }

    public void kLine(
            String symbol, DataSource.DataCallback<Resource<List<KData>>> callback) {
        this.symbol = symbol;
        this.toDate = System.currentTimeMillis();
        this.mCallback = callback;
        callback.onResult(Resource.loading());

        DataRepository.get().visualQuotation(symbol, resolution, fromDate, toDate, result -> {
            if (result.getCode() == 0) {
                List<VisualQuotation.DataBean> data = result.getData();
                List<KData> kDataList = new LinkedList<>();
                for (VisualQuotation.DataBean datum : data) {
                    long time = datum.getId() * 1000;
                    kDataList.add(0, new KData(time, datum.getOpen(), datum.getClose(),
                            datum.getHigh(), datum.getLow(), datum.getVol()));
                }

                callback.onResult(Resource.success(kDataList));
            } else {
                callback.onResult(Resource.empty());
            }
        });
    }

    // 交易对价格
    public void marketPair(String symbol, DataSource.DataCallback<MarketPair> callback) {
        mMarketPairTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                DataRepository.get().marketPairData(symbol, result -> {
                    if (result.isSucceed()) {
                        callback.onResult(result);
                    }
                });
            }
        }, 0, 1000 * 20);
    }

    // 买卖盘记录
    public void record(String symbol, DataSource.DataCallback<Resource<List<OrderRecord>>> callback) {
        callback.onResult(Resource.loading());

        DataRepository.get().entrustQueue(symbol, result -> {
            EntrustQueue.DataBean resultData = result.getData();
            if (resultData != null && result.isSucceed()) {
                List<OrderRecord> list = new ArrayList<>();
                List<EntrustQueue.DataBean.Bean> buy = resultData.getBuy();
                List<EntrustQueue.DataBean.Bean> sell = resultData.getSell();

                if (buy == null || sell == null){
                    callback.onResult(Resource.empty());
                    return;
                }

                if (buy.size() > sell.size()) {
                    for (EntrustQueue.DataBean.Bean bean : buy) {
                        OrderRecord record = new OrderRecord();
                        record.setBuyNumber(bean.getSurplus_num());
                        record.setBuyPrice(bean.getOn_price());
                        list.add(record);
                    }

                    for (int i = 0; i < sell.size(); i++) {
                        OrderRecord record = list.get(i);
                        EntrustQueue.DataBean.Bean bean = sell.get(i);
                        record.setSaleNumber(bean.getSurplus_num());
                        record.setSalePrice(bean.getOn_price());
                    }
                } else {
                    for (EntrustQueue.DataBean.Bean bean : sell) {
                        OrderRecord record = new OrderRecord();
                        record.setBuyNumber(bean.getSurplus_num());
                        record.setBuyPrice(bean.getOn_price());
                        list.add(record);
                    }

                    for (int i = 0; i < buy.size(); i++) {
                        OrderRecord record = list.get(i);
                        EntrustQueue.DataBean.Bean bean = buy.get(i);
                        record.setSaleNumber(bean.getSurplus_num());
                        record.setSalePrice(bean.getOn_price());
                    }
                }

                if (list.isEmpty()){
                    callback.onResult(Resource.empty());
                } else {
                    callback.onResult(Resource.success(list));
                }

            } else if (result.isNotNetwork()) {
                callback.onResult(Resource.notNetwork());
            } else {
                callback.onResult(Resource.error(result.getMsg()));
            }
        });
    }

    public void clearTimer() {
        mMarketPairTimer.cancel();
        mMarketPairTimer = null;
    }
}
